package com.ethink.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.db.PageUtils;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.framework.common.web.context.SPRequestContextHolder;
import com.ethink.order.api.info.GroupMateDetailInfo;
import com.ethink.order.api.info.GroupMateInfo;
import com.ethink.order.api.request.GroupMateAddRequest;
import com.ethink.order.api.request.GroupMateQueryRequest;
import com.ethink.order.api.request.GroupMateUpdateRequest;
import com.ethink.order.api.response.GroupMateAddResponse;
import com.ethink.order.api.response.GroupMateDetailResponse;
import com.ethink.order.common.entity.GroupMate;
import com.ethink.order.common.entity.GroupMateDetail;
import com.ethink.order.common.mapper.GroupMateMapper;
import com.ethink.order.converter.GroupMateConverter;
import com.ethink.order.service.GroupMateDetailService;
import com.ethink.order.service.GroupMateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 组套商品表 Service接口实现
 *
 * @author default
 * @date 2023-02-22
 */
@Slf4j
@Service
public class GroupMateServiceImpl implements GroupMateService {

    @Autowired
    private GroupMateMapper groupMateMapper;

    @Autowired
    private GroupMateDetailService groupMateDetailService;

    @Autowired
    private GroupMateConverter groupMateConverter;

    @Override
    public Page<GroupMateInfo> queryGroupMate(GroupMateQueryRequest request) {
        return groupMateMapper.queryGroupMate(PageUtils.buildPage(request), request);
    }

    @Override
    public GroupMateDetailResponse getGroupMateById(Long groupMateId) {
        GroupMateInfo father = groupMateMapper.getGroupMateById(groupMateId);
        GroupMateDetailResponse res = new GroupMateDetailResponse();
        res.setMain(father);
        List<GroupMateDetailInfo> children = groupMateDetailService.listByGroupMateId(groupMateId);
        res.setItems(children);
        BigDecimal totalSalePrice = children.stream()
                .map(GroupMateDetailInfo::getSalePrice)
                .reduce(new BigDecimal(0), (m, n) -> m.add(n));
        father.setTotalSalePrice(totalSalePrice);
        return res;
    }

    @Override
    public List<GroupMateInfo> listGroupMate(GroupMateQueryRequest request) {
        return groupMateMapper.listGroupMate(request);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public GroupMateAddResponse addGroupMate(GroupMateAddRequest request) {
        GroupMateAddResponse response = new GroupMateAddResponse();
        GroupMate groupMate = new GroupMate();
        BeanUtils.copyProperties(request, groupMate);
        // FIXME set默认字段
        groupMate.setGeneraCode("30000000");
        groupMate.setGeneraCodeName("美妆");
        groupMate.setCreateUser(SPRequestContextHolder.getCurrentSystemUserLoginName());
        groupMate.setCreateTime(LocalDateTime.now());
        groupMate.setIsDeleted(Boolean.FALSE);
        int count = groupMateMapper.insert(groupMate);
        // 明细表
        List<GroupMateDetail> childrenList = new ArrayList<>();
        request.getItems().forEach(item -> {
            GroupMateDetail children = BeanUtil.copyProperties(item, GroupMateDetail.class);
            children.setGroupMateId(groupMate.getId());
            children.setIsDeleted(Boolean.FALSE);
            children.setCreateTime(LocalDateTime.now());
            childrenList.add(children);
        });
        // 添加子表
        boolean childrenFlag = groupMateDetailService.saveBatch(childrenList);
        if (!(count > 0 && childrenFlag)) {
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "添加失败");
        }
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateGroupMate(GroupMateUpdateRequest request) {
        LambdaUpdateWrapper<GroupMate> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(GroupMate::getId, request.getId());
        // FIXME 按实际业务需求set
        updateWrapper.set(GroupMate::getMateSku, request.getMateSku());
        updateWrapper.set(GroupMate::getMateSkuName, request.getMateSkuName());
        updateWrapper.set(GroupMate::getSaleSubChannel, request.getSaleSubChannel());
        updateWrapper.set(GroupMate::getGeneraCode, request.getGeneraCode());
        updateWrapper.set(GroupMate::getGeneraCodeName, request.getGeneraCodeName());
        updateWrapper.set(GroupMate::getMinorDefectsCode, request.getMinorDefectsCode());
        updateWrapper.set(GroupMate::getMinorDefectsCodeName, request.getMinorDefectsCodeName());
        updateWrapper.set(GroupMate::getSubclassCode, request.getSubclassCode());
        updateWrapper.set(GroupMate::getSubclassCodeName, request.getSubclassCodeName());
        updateWrapper.set(GroupMate::getProductSpecification, request.getProductSpecification());
        updateWrapper.set(GroupMate::getBrandCode, request.getBrandCode());
        updateWrapper.set(GroupMate::getBrandName, request.getBrandName());
        updateWrapper.set(GroupMate::getUnitCode, request.getUnitCode());
        updateWrapper.set(GroupMate::getUnitName, request.getUnitName());
        updateWrapper.set(GroupMate::getUpdateUser, SPRequestContextHolder.getCurrentSystemUserLoginName());
        updateWrapper.set(GroupMate::getUpdateTime, LocalDateTime.now());
        int count = groupMateMapper.update(null, updateWrapper);
        // 先删除所有明细表的数据
        boolean remove = groupMateDetailService.remove(Wrappers.<GroupMateDetail>lambdaUpdate()
                .eq(GroupMateDetail::getGroupMateId, request.getId())
                .set(GroupMateDetail::getIsDeleted, Boolean.TRUE)
        );
        // 添加明细表的数据
        List<GroupMateDetail> insertData = new ArrayList<>();
        request.getItems().forEach(item -> {
            GroupMateDetail children = new GroupMateDetail();
            children.setGroupMateId(request.getId());
            children.setMateSku(item.getMateSku());
            children.setQty(item.getQty());
            children.setCreateTime(LocalDateTime.now());
            children.setIsDeleted(Boolean.FALSE);
            children.setCreateUser(SPRequestContextHolder.getCurrentSystemUserLoginName());
            insertData.add(children);
        });
        boolean flag = groupMateDetailService.saveBatch(insertData);
        if (!(count > 0 && remove && flag)) {
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "修改失败");
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteGroupMate(Long groupMateId) {
        LambdaUpdateWrapper<GroupMate> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(GroupMate::getId, groupMateId);
        updateWrapper.set(GroupMate::getIsDeleted, Boolean.TRUE);
        int count = groupMateMapper.update(null, updateWrapper);
        // 修改子表
        boolean childrenFlag = groupMateDetailService.update(Wrappers.<GroupMateDetail>lambdaUpdate()
                .eq(GroupMateDetail::getGroupMateId, groupMateId)
                .set(GroupMateDetail::getIsDeleted, Boolean.TRUE)
        );
        if (!(count > 0 && childrenFlag)) {
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "删除失败");
        }
        return true;
    }

    /**
     * 根据渠道查商品
     *
     * @param saleSubChannel
     * @return
     */
    @Override
    public List<String> getGroupMateSkuList(String saleSubChannel) {
        return groupMateMapper.selectList(Wrappers.<GroupMate>query()
                .select("DISTINCT `mate_sku`")
                .lambda()
                .eq(GroupMate::getSaleSubChannel, saleSubChannel)
        ).stream().map(GroupMate::getMateSku).collect(Collectors.toList());
    }

    /**
     * 根据渠道和sku查询数据
     *
     * @param saleSubChannel
     * @param groupMateSku
     * @return
     */
    @Override
    public GroupMateDetailResponse getGroupMateByGroupMateSku(String saleSubChannel, String groupMateSku) {
        GroupMate main = groupMateMapper.selectOne(Wrappers.<GroupMate>lambdaQuery()
                .eq(GroupMate::getSaleSubChannel, saleSubChannel)
                .like(GroupMate::getMateSku, groupMateSku)
        );
        GroupMateInfo copyMain = BeanUtil.copyProperties(main, GroupMateInfo.class);
        List<GroupMateDetail> items = groupMateDetailService.list(Wrappers.<GroupMateDetail>lambdaUpdate()
                .eq(GroupMateDetail::getGroupMateId, main.getId())
        );
        GroupMateDetailResponse res = new GroupMateDetailResponse();
        res.setMain(copyMain);
        List<GroupMateDetailInfo> children = new ArrayList<>();
        items.forEach(item -> {
            GroupMateDetailInfo groupMateDetailInfo = BeanUtil.copyProperties(item, GroupMateDetailInfo.class);
            children.add(groupMateDetailInfo);
        });
        BigDecimal totalSalePrice = children.stream()
                .map(GroupMateDetailInfo::getSalePrice)
                .reduce(new BigDecimal(0), (m, n) -> m.add(n));
        copyMain.setTotalSalePrice(totalSalePrice);
        res.setItems(children);
        return res;
    }
}
